//
//  KDJ.m
//  AppFinance
//
//  Created by wei on 12-7-15.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "AFKDJ.h"

@implementation AFKDJ

static AFKDJ *_kdj = nil;

static float _kpiMaxKdj = 0;
static float _kpiMinKdj = 100000000;

static float _kpiLastK = 0;
static float _kpiLastD = 0;
static float _kpiLastJ = 0;

+(AFKDJ*) app{
    if (_kdj == nil) {
        _kdj = [[self alloc] init];
    }
    return _kdj;
}

+(float) kpiMaxKdj{
    return _kpiMaxKdj;
}

+(float) kpiMinKdj{
    return _kpiMinKdj;
}

+(float) kpiLastK{
    return _kpiLastK;
}

+(float) kpiLastD{
    return _kpiLastD;
}

+(float) kpiLastJ{
    return _kpiLastJ;
}

int kdj_iParam[] = {9,3,3};

-(void) initKlineArray:(NSArray *)_kLineArray{
    kLineArray = _kLineArray;
    
    _kpiMaxKdj = 0;
    _kpiLastK = 0;
    _kpiLastD = 0;
    _kpiLastJ = 0;
    
    _kArray = nil;
    _dArray = nil;
    _jArray = nil;
    
    _kpiMaxKdj = 0;
    _kpiMinKdj = 100000000;
}

-(void) kdjData{
    
    float n1 = kdj_iParam[0];
    float n2 = kdj_iParam[1];
    float n3 = kdj_iParam[2];
    
    if(kLineArray == nil || n1 > [kLineArray count] || n1 < 1){
        return;
    }
    
    _kArray = [NSMutableArray array];
    _dArray = [NSMutableArray array];
    _jArray = [NSMutableArray array];
    
    n2 = n2 > 0 ? n2 : 3;
    n3 = n3 > 0 ? n3 : 3;
    
    NSDictionary *dict;
    float high = 0;
    float low = 0;
    float close = 0;
    
    // 获取最高点 和 最底点
    float maxhigh = 0;
    float minlow = 0;
    dict = [kLineArray objectAtIndex:(n1 - 1)];
    high = [[dict objectForKey:AF_K_MARKET_HIGH] floatValue];
    low = [[dict objectForKey:AF_K_MARKET_LOW] floatValue];
    
    maxhigh = high;
    minlow = low;
    
    for(int j = n1 - 1; j >= 0; j--) {
        dict = [kLineArray objectAtIndex:j];
        high = [[dict objectForKey:AF_K_MARKET_HIGH] floatValue];
        low = [[dict objectForKey:AF_K_MARKET_LOW] floatValue];
        close = [[dict objectForKey:AF_K_MARKET_CLOSE] floatValue];
        
        if(maxhigh < high)
            maxhigh = high;
        if(low < minlow)
            minlow = low;
    }
    
    // 计算 rsv
    float rsv = 0;
    if(maxhigh <= minlow){
        rsv = 50;
    }
    else{
        dict = [kLineArray objectAtIndex:(n1-1)];
        close = [[dict objectForKey:AF_K_MARKET_CLOSE] floatValue];
        rsv = ((close - minlow) / (maxhigh - minlow)) * 100.0f;
    }
    float prersv = rsv;
    
    for(int i = 0; i < n1; i++) {
        [_kArray addObject:[NSNumber numberWithFloat:0]];
        [_dArray addObject:[NSNumber numberWithFloat:0]];
        [_jArray addObject:[NSNumber numberWithFloat:0]];
    }
    
    float pre_kvalue = 0;
    float kvalue = 0;
    float dvalue = 0;
    float jvalue = 0;
    
    int count = (int)[kLineArray count];
    for(int i = n1; i < count; i++) {
        dict = [kLineArray objectAtIndex:i];
        maxhigh = [[dict objectForKey:AF_K_MARKET_HIGH] floatValue];
        minlow = [[dict objectForKey:AF_K_MARKET_LOW] floatValue];
        close = [[dict objectForKey:AF_K_MARKET_CLOSE] floatValue];
        
        for(int j = i - 1; j > i - n1; j--) {
            dict = [kLineArray objectAtIndex:j];
            high = [[dict objectForKey:AF_K_MARKET_HIGH] floatValue];
            low = [[dict objectForKey:AF_K_MARKET_LOW] floatValue];
            
            if(maxhigh < high)
                maxhigh = high;
            if(minlow > low)
                minlow = low;
        }
        
        if(maxhigh <= minlow) {
            rsv = prersv;
        } else {
            prersv = rsv;
            rsv = ((close - minlow) / (maxhigh - minlow)) * 100.0f;
        }
        kvalue = (pre_kvalue * (float)(n2 - 1)) / (float)n2 + rsv / (float)n2;
        dvalue = kvalue / (float)n3 + (pre_kvalue * (float)(n3 - 1)) / (float)n3;
        jvalue = 3.0f * kvalue - 2.0f *dvalue;
        
        pre_kvalue = kvalue;
        
        if (kvalue > _kpiMaxKdj) {
            _kpiMaxKdj = kvalue;
        }
        if (dvalue > _kpiMaxKdj) {
            _kpiMaxKdj = dvalue;
        }
        if (jvalue > _kpiMaxKdj) {
            _kpiMaxKdj = jvalue;
        }
        
        if (kvalue < _kpiMinKdj) {
            _kpiMinKdj = kvalue;
        }
        if (dvalue < _kpiMinKdj) {
            _kpiMinKdj = dvalue;
        }
        if (jvalue < _kpiMinKdj) {
            _kpiMinKdj = jvalue;
        }
        
        //NSLog(@" kvalue = %f  dvalue = %f  jvalue = %f",kvalue,dvalue,jvalue);
        
        [_kArray addObject:[NSNumber numberWithFloat:kvalue]];
        [_dArray addObject:[NSNumber numberWithFloat:dvalue]];
        [_jArray addObject:[NSNumber numberWithFloat:jvalue]];
    }
}

-(NSMutableArray *) kArrayData{
    return _kArray;
}

-(NSMutableArray *) dArrayData{
    return _dArray;
}

-(NSMutableArray *) jArrayData{
    return _jArray;
}

@end
